package juc;

import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.PriorityQueue;
import java.util.concurrent.*;

/**
 * @author: feiwang_6
 * @create: 2020/6/27 18:49
 * @description:
 */
public class ThreadCurrentUtil {
    
    public static void main(String[] args) {
        PriorityQueue<Integer> queue = new PriorityQueue<>();
        queue.add(1);
        queue.add(2);
        queue.add(3);
        queue.add(null);
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
    }
    
    @Test
    public void converLinked(){
        List<Integer> list = Arrays.asList(1, 3, 45, 100, 109);
        int sum = list.stream().filter(f -> f >= 100).mapToInt(f -> f).sum();
        System.out.println(sum);
    }
    
    @Test
    public void testDownLatch() throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(4);
        String s = "";
        s.intern();
        Runnable runnable = () ->{
            latch.countDown();
            System.out.println(latch.getCount());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            latch.countDown();
            System.out.println(latch.getCount());
            latch.countDown();
            System.out.println(latch.getCount());
            latch.countDown();
            System.out.println(latch.getCount());
            latch.countDown();
            System.out.println(latch.getCount());
        };
        
        Thread thread = new Thread(runnable);
        thread.start();
        latch.await(5, TimeUnit.SECONDS);
        latch.await();
    }
    
    @Test
    public void testCyclicBarrier() throws Exception {
        CyclicBarrier c = new CyclicBarrier(3);
        
        Runnable runnable = () -> {
            String name = Thread.currentThread().getName();
            try {
                c.await();
                System.out.println("1111111  " + name);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        };
        
        for(int i = 1; i <= 9; i++){
            Thread t = new Thread(runnable);
            t.setName("name" + i);
            Thread.sleep(1000);
            t.start();
        }
        
        Thread.sleep(30000);
    }

    @Test
    public void testSemaphore() throws Exception {
        Semaphore semaphore = new Semaphore(3);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    semaphore.acquire();
                    System.out.println("1111111111");
                    Thread.sleep(2000);
                    System.out.println("2222222222");
                    semaphore.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        for(int i = 0; i < 10; i++){
            new Thread(runnable).start();
        }
        Thread.sleep(10000);
    }
    
    @Test
    public void testExchanger() throws InterruptedException {
        Exchanger<String> exchanger = new Exchanger<>();
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                String name = Thread.currentThread().getName();
                try {
                    String exchange = exchanger.exchange(name);
                    System.out.println("当前线程：" + name + " 交互线程：" + exchange);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        for(int i = 0; i < 3; i++){
            Thread thread = new Thread(runnable);
            thread.setName("线程-" + i);
            thread.start();
        }
        
        Thread.sleep(4000);
    }
    
    @Test
    public void testExecutor() throws Exception {
        ExecutorService service = Executors.newFixedThreadPool(1);
        Executors.newSingleThreadExecutor();
        service.execute(() -> {
            System.out.println("1111111111111 start");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("1111111111111 end");
        });

        service.execute(() -> {
            System.out.println("222222222222 start");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("222222222222 end");
        });

        service.execute(() -> {
            System.out.println("333333333333 start");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("333333333333 end");
        });
        Thread.sleep(1000);
        service.shutdownNow();
        System.out.println("pool shutdown");
        Thread.sleep(20000);
    }
}
